package com.qianniu.napi.common.util;

import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.qianniu.napi.common.config.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.security.MessageDigest;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;

public class EncryptUtil {

    private static final Logger logger = LoggerFactory.getLogger(EncryptUtil.class);

    /*
     * md5加密
     * @param s：要被加密的字符串
     */
    public final static String md5(String s) {
        char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                'a', 'b', 'c', 'd', 'e', 'f'};
        try {
            byte[] strTemp = s.getBytes();
            MessageDigest mdTemp = MessageDigest.getInstance("MD5");
            mdTemp.update(strTemp);
            byte[] md = mdTemp.digest();
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        } catch (Exception e) {
            return null;
        }
    }

    /*
     * md5加密
     * @param s：要被加密的字符串
     */
    public final static String md5t16(String s) {
        char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                'a', 'b', 'c', 'd', 'e', 'f'};
        try {
            byte[] strTemp = s.getBytes();
            MessageDigest mdTemp = MessageDigest.getInstance("MD5");
            mdTemp.update(strTemp);
            byte[] md = mdTemp.digest();
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str).substring(0,16);
        } catch (Exception e) {
            return null;
        }
    }

    /*
     * Base64处理
     */
    public static String base64Encode(String src){
        //Base64 b64 = new Base64();
        BASE64Encoder b64 = new BASE64Encoder();
        //log.debug("encode src:"+src);
        try{
            String encode = new String(b64.encode(src.getBytes("GBK")));
            encode = encode.replaceAll(" ", "").replaceAll("\r", "").replaceAll("\n", "");
            //log.debug("encode :"+encode);
            return encode;
        }catch(UnsupportedEncodingException e){
            return null;
        }
    }

    /*
     * encode处理
     */
    public static String encode(String src){
        String key = getKey(8, 18);
        //Base64 b64 = new Base64();
        BASE64Encoder b64 = new BASE64Encoder();
        String encodeStr = "";
        try {
            encodeStr = new String(b64.encode(replacement(src, key).getBytes("GBK")));
        } catch (UnsupportedEncodingException e) {
        }
        //log.error("encode:"+encodeStr);
        return encodeStr;
    }
    public static String base64Decode(String src){
        //Base64 b64 = new Base64();
        BASE64Decoder b64 = new BASE64Decoder();
        try{
            String decode = new String(b64.decodeBuffer(src));
            return decode;
        }catch(Exception e){
            return null;
        }
    }

    public static String decode(String src){
        String key = getKey(8, 18);
        //Base64 b64 = new Base64();
        BASE64Decoder b64 = new BASE64Decoder();
        String decodeStr = "";
        try {
            decodeStr = replacement(new String(b64.decodeBuffer(src)),key);
        } catch (Exception e) {
        }

        return decodeStr;
    }

    protected static String getKey(int start, int lenght){
        String md5Str = md5(Constants.ENCODE_KEY);
        return md5Str.substring(start, start+lenght);
    }

    private static String replacement(String src, String key) {
        String result = null;
        try {
            byte[] keyBytes = key.getBytes("GBK");
            int keyLen = keyBytes.length;
            byte[] srcBytes = src.getBytes("GBK");
            int len = srcBytes.length;
            byte[] bb = new byte[len];
            for (int i = 0; i < len; i++) {
                int k = i % keyLen;
                byte b = (byte) (srcBytes[i] ^ keyBytes[k]);
                bb[i] = b;
            }
            result = new String(bb);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    /**
     * url解码
     * @param url
     * @param charset
     * @return
     */
    public static String urlDecode(String url, String charset){
        try {
            url = URLDecoder.decode(url, charset);
        } catch (UnsupportedEncodingException e) {
        }
        return url;
    }

    /**
     * url解码
     * @param map
     * @return
     */
    public static Map<String,String> delEmptyKey(Map<String,String> map){
        if(map==null) return map;
        Iterator iterator = map.keySet().iterator();
        Map<String,String> newMap = Maps.newHashMap(map);
        while(iterator.hasNext()){
            String key =  (String)iterator.next();
            if(Strings.isNullOrEmpty(map.get(key))){
                newMap.remove(key);
            }
        }

        return newMap;
    }

    public static String noRepeat(String str){
        if(Strings.isNullOrEmpty(str)) return null ;
        String[] input = str.split("，");
        HashSet<String> set =new HashSet<String>();
        for(String item:input) {
            if (Strings.isNullOrEmpty(item))continue;
            set.add(item);
        }

        StringBuilder sb = new StringBuilder();
        for(String item:set) {
            sb.append("，"+item);
        }
        String result = sb.toString();
        if(result.length()>0)result = result.substring(1);
        return result;
    }

    public static Object replaceNull(Object model,String replaceText) {
        if(replaceText==null||replaceText.equals("")) return model;

        try {
            // 获取实体类的所有属性，返回Field数组
            Field[] field = model.getClass().getDeclaredFields();
            // 获取属性的名字
            String[] modelName = new String[field.length];
            String[] modelType = new String[field.length];

            for (int i = 0; i < field.length; i++) {
                // 获取属性的名字
                String name = field[i].getName();
                modelName[i] = name;
                // 获取属性类型
                String type = field[i].getGenericType().toString();
                modelType[i] = type;

                //关键。。。可访问私有变量
                field[i].setAccessible(true);
                //给属性设置
                //field[i].set(model, field[i].getType().getConstructor(field[i].getType()).newInstance("kou"));

                // 将属性的首字母大写
                name = name.replaceFirst(name.substring(0, 1), name.substring(0, 1).toUpperCase());

                if (type.equals("class java.lang.String")) {
                    // 如果type是类类型，则前面包含"class "，后面跟类名
                    Method getMethod = model.getClass().getMethod("get" + name);
                    if(getMethod.invoke(model)!=null)continue;

                    Method setMethod = model.getClass().getMethod("set" + name,String.class);
                    // 调用getter方法获取属性值
                    String value = (String) setMethod.invoke(model,replaceText);
                }
            }
        }catch (Exception e){
            logger.error("======replaceNull error======",e);
        }

        return model;
    }


    public static void main(String[] args){

//        replaceNull(baikeDO,"未知部门");
//        System.out.println("baikeDO.getDepartName="+baikeDO.getDepartName());
//        System.out.println("baikeDO.getIssue="+baikeDO.getIssue());


    }

    private static String byteArrayToHexString(byte b[]) {
        StringBuffer resultSb = new StringBuffer();
        for (int i = 0; i < b.length; i++)
            resultSb.append(byteToHexString(b[i]));

        return resultSb.toString();
    }

    private static String byteToHexString(byte b) {
        int n = b;
        if (n < 0)
            n += 256;
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }

    public static String MD5Encode(String origin, String charsetname) {
        String resultString = null;
        try {
            resultString = new String(origin);
            MessageDigest md = MessageDigest.getInstance("MD5");
            if (charsetname == null || "".equals(charsetname))
                resultString = byteArrayToHexString(md.digest(resultString
                        .getBytes()));
            else
                resultString = byteArrayToHexString(md.digest(resultString
                        .getBytes(charsetname)));
        } catch (Exception exception) {
        }
        return resultString;
    }

    private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
}
